package com.wx.task.future;

import cn.hutool.core.util.RandomUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * CompletionStage 测试
 * CompletionStage
 * 完成阶段
 *
 * @author wang.xun
 * @date 2023/08/03
 */
@Slf4j
public class CompletionStageTest {
    public static void main(String[] args) {


        CompletableFuture<?> f = CompletableFuture.supplyAsync(() -> "QQ")
                .thenApply(m -> {
                    byte[] bytes = m.getBytes();
                    Integer[] ints = new Integer[bytes.length];
                    for (int i = 0; i < bytes.length; i++) {
                        ints[i] = (int) bytes[i];

                    }

                    List<Integer> collect = Stream.of(ints).map((index) -> index + 1).collect(Collectors.toList());

                    return collect;

                })
                .thenApply(v -> v.stream().map((m) -> (char) (int) m).collect(Collectors.toList()));

        try {
            Object o = f.get();
            log.info("{}", o);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        }


        CompletableFuture<String> f4 =
                CompletableFuture.supplyAsync(() -> {
                    int t = RandomUtil.getRandom().nextInt(0, 2);
                    try {
                        log.info("f4 要睡眠 {}s", t);
                        TimeUnit.SECONDS.sleep(t);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    return String.valueOf(t);
                });

        CompletableFuture<String> f5 =
                CompletableFuture.supplyAsync(() -> {
                    int t = RandomUtil.getRandom().nextInt(5, 10);
                    try {
                        log.info("f5 要睡眠 {}s", t);
                        TimeUnit.SECONDS.sleep(t);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    return String.valueOf(t);
                });
        // 任意执行完就返回
        CompletableFuture<String> f6 =
                f4.applyToEither(f5, s -> s);

        log.info("最后睡眠：{}s", f6.join());


        CompletableFuture<Integer> f7 = CompletableFuture.supplyAsync(() -> {
            log.info("开始计算");
                    return 7 / 1;})
                .thenApplyAsync(r -> {
                    log.info("开始第二步计算");
                    return r * 10;
                })
                .exceptionally (e -> {
                    log.error("异常结果：", e);
                    return -1;})
                .whenCompleteAsync((rs ,err)->{
                            log.info("结果 {}",rs);
                            log.error("异常结果 ",err);
                        });


        log.info("f7 结果：{}",f7.join());

    }


}
